#include <interface.h>
#include <iostream>

DECLARE_DRAWABLE_BEGIN(LinearGradient, "Test/LinearGradient", 0,1,1)
  virtual void init() override {
    shader_.loadPath("LinearGradient.vs", "LinearGradient.fs");

    float vertices[] = {
       0.9f,  0.9f, 0.0f,  // top right
       0.9f, -0.9f, 0.0f,  // bottom right
      -0.9f, -0.9f, 0.0f,  // bottom left
      -0.9f,  0.9f, 0.0f   // top left 
    };
    unsigned int indices[] = {  // note that we start from 0!
      0, 1, 3,  // first Triangle
      1, 2, 3   // second Triangle
    };

    glGenVertexArrays(1, &VAO_);
    glGenBuffers(1, &VBO_);
    glGenBuffers(1, &EBO_);

    glBindVertexArray(VAO_);
    glBindBuffer(GL_ARRAY_BUFFER, VBO_);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    glBindVertexArray(0);
  }
  virtual void uninit() override {
    glDeleteVertexArrays(1, &VAO_);
    glDeleteBuffers(1, &VBO_);
    glDeleteBuffers(1, &EBO_);
    shader_.free();
  }
  virtual void render() override {
    shader_.use();

    int width, height;
    window_->getSize(&width, &height);
    glm::vec2 resolution(width, height);
    shader_.setVec2("resolution", resolution);
    shader_.setVec2("gradientStartPos", 0.f, 0.f);
    shader_.setVec2("gradientEndPos", width, height);

    int numStops = 3;
    shader_.setInt("numStops", numStops);
    glm::vec4 colors[3] = {
      glm::vec4(1.0, 0.0, 0.0, 1.0),
      glm::vec4(0.0, 1.0, 0.0, 1.0),
      glm::vec4(0.0, 0.0, 1.0, 1.0)
    };
    GLfloat stops[3] = {
      0.0, 0.5, 1.0
    };
    glUniform4fv(glGetUniformLocation(shader_.id, "colors"), numStops, (const GLfloat*)&colors[0]);
    glUniform1fv(glGetUniformLocation(shader_.id, "stops"), numStops, (const GLfloat*)&stops[0]);

    glBindVertexArray(VAO_);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  }
 protected:
  GLuint shaderProgram_;
  GLuint VAO_, VBO_, EBO_;
  Shader shader_;
DECLARE_DRAWABLE_END(LinearGradient)